using System.Collections.Generic;
using System;
using SharpArch.Core;
using GoldenBicycleCompany.Core;
using GoldenBicycleCompany.ApplicationServices.ViewModels;
using GoldenBicycleCompany.Core.QueryDtos;
using GoldenBicycleCompany.Core.RepositoryInterfaces;
 

namespace GoldenBicycleCompany.ApplicationServices
{
    public class BicycleManagementService : IBicycleManagementService
    {
        public BicycleManagementService(IBicycleRepository bicycleRepository) {
            Check.Require(bicycleRepository != null, "bicycleRepository may not be null");

            this.bicycleRepository = bicycleRepository;
        }

        public Bicycle Get(int id) {
            return bicycleRepository.Get(id);
        }

        public IList<Bicycle> GetAll() {
            return bicycleRepository.GetAll();
        }

        public IList<BicycleDto> GetBicycleSummaries() {
            return bicycleRepository.GetBicycleSummaries();
        }

        public BicycleFormViewModel CreateFormViewModel() {
            BicycleFormViewModel viewModel = new BicycleFormViewModel();
            return viewModel;
        }

        public BicycleFormViewModel CreateFormViewModelFor(int bicycleId) {
            Bicycle bicycle = bicycleRepository.Get(bicycleId);
            return CreateFormViewModelFor(bicycle);
        }

        public BicycleFormViewModel CreateFormViewModelFor(Bicycle bicycle) {
            BicycleFormViewModel viewModel = CreateFormViewModel();
            viewModel.Bicycle = bicycle;
            return viewModel;
        }

        public ActionConfirmation SaveOrUpdate(Bicycle bicycle) {
            if (bicycle.IsValid()) {
                bicycleRepository.SaveOrUpdate(bicycle);

                ActionConfirmation saveOrUpdateConfirmation = ActionConfirmation.CreateSuccessConfirmation(
                    "The bicycle was successfully saved.");
                saveOrUpdateConfirmation.Value = bicycle;

                return saveOrUpdateConfirmation;
            }
            else {
                bicycleRepository.DbContext.RollbackTransaction();

                return ActionConfirmation.CreateFailureConfirmation(
                    "The bicycle could not be saved due to missing or invalid information.");
            }
        }

        public ActionConfirmation UpdateWith(Bicycle bicycleFromForm, int idOfBicycleToUpdate) {
            Bicycle bicycleToUpdate = 
                bicycleRepository.Get(idOfBicycleToUpdate);
            TransferFormValuesTo(bicycleToUpdate, bicycleFromForm);

            if (bicycleToUpdate.IsValid()) {
                ActionConfirmation updateConfirmation = ActionConfirmation.CreateSuccessConfirmation(
                    "The bicycle was successfully updated.");
                updateConfirmation.Value = bicycleToUpdate;

                return updateConfirmation;
            }
            else {
                bicycleRepository.DbContext.RollbackTransaction();

                return ActionConfirmation.CreateFailureConfirmation(
                    "The bicycle could not be saved due to missing or invalid information.");
            }
        }

        public ActionConfirmation Delete(int id) {
            Bicycle bicycleToDelete = bicycleRepository.Get(id);

            if (bicycleToDelete != null) {
                bicycleRepository.Delete(bicycleToDelete);

                try {
                    bicycleRepository.DbContext.CommitChanges();
                    
                    return ActionConfirmation.CreateSuccessConfirmation(
                        "The bicycle was successfully deleted.");
                }
                catch {
                    bicycleRepository.DbContext.RollbackTransaction();

                    return ActionConfirmation.CreateFailureConfirmation(
                        "A problem was encountered preventing the bicycle from being deleted. " +
                        "Another item likely depends on this bicycle.");
                }
            }
            else {
                return ActionConfirmation.CreateFailureConfirmation(
                    "The bicycle could not be found for deletion. It may already have been deleted.");
            }
        }

        private void TransferFormValuesTo(Bicycle bicycleToUpdate, Bicycle bicycleFromForm) {
            bicycleToUpdate.BicycleManufacturer = bicycleFromForm.BicycleManufacturer;
            bicycleToUpdate.BicycleType = bicycleFromForm.BicycleType;
            bicycleToUpdate.Color = bicycleFromForm.Color;
            bicycleToUpdate.MaintenanceRecords = bicycleFromForm.MaintenanceRecords;
            bicycleToUpdate.BarcodeIdNumber = bicycleFromForm.BarcodeIdNumber;
            bicycleToUpdate.Model = bicycleFromForm.Model;
            bicycleToUpdate.YearPurchased = bicycleFromForm.YearPurchased;
            bicycleToUpdate.IsRented = bicycleFromForm.IsRented;
            bicycleToUpdate.IsUnderMaintenance = bicycleFromForm.IsUnderMaintenance;
        }

        IBicycleRepository bicycleRepository;
    }
}
